某大厂如何利用系统漏洞,控制用户整个手机系统
攻击竞争对手 App
窃取用户隐私数据
逃避隐私合规监管
用户无法卸载
改写系统配置文件为自身保活
隐蔽安装,提升装机量
伪造提升 DAU/MAU
通过远端“云控开关”控制非法行为的启动与暂停
......
PS:我已经将相关违规的 dex 转成了 Java 文件放到文末了,有兴趣的同学可以前往下载
在国外该 APP 已经被 GooglePlay 下架。谷歌公司发言人埃德·费尔南德斯在一份声明中表示:“将拼多多 APP 下架是一种安全预防措施,谷歌的软件防护服务 Google Play Protect 将会阻止用户从谷歌商店中下载拼多多的 APP,并且已经下载了该 APP 的用户也会收到警告,提示他们进行卸载”。
https://techcrunch.com/2023/03/20/google-flags-apps-made-by-popular-chinese-e-commerce-giant-as-malware/
俄罗斯知名的反病毒软件卡巴斯基也石锤它,该实验室的研究人员证实该 App 安装恶意代码,操控用户的手机系统。
该 APP 利用了 Android Parcel 序列化和反序列化不匹配系列漏洞,绕过系统校验,进行提权,获取系统级 StartAnyWhere 能力。这个漏洞最早是由 @BednarTildeOne 在 2014 年提交的 ParceledListSlice 漏洞。
什么是序列化和反序列化不匹配?
在 Android 中通过 Parcelable 序列化对象,而实现 Parcelable 接口,需要实现 readFromParcel
和 writeToParcel
函数。
dest.writeLong(txPower);
}
private void readFromParcel(Parcel in) {
txPower = in.readInt();
}
对变量 txPower
在写入的时候通过 writeLong
方法写入,但是在读取的时候通过 readInt
方法读取。这就是序列化和反序列化不匹配。
由于 Android 系统在大量的使用 IPC 都会进行序列化和反序列化,许多操作都会在 system_server 、Settings 应用、普通应用中来回传递。所以这个问题是非常常见的,这类问题对于普通人来说一般不会引起注意,但是 hacker 却可以利用它做出很多高危的事情,比如利用 Settings 和 system_server 进程的权限进行提权,发送任意 Intent,启动任意 Activity。
我们用 CVE-2017-13288 漏洞来举个例子:
普通 AppB 传递一个 Bundle 对象到
system_server
进程,这个 Bundle 对象中包含的一个恶意键值对{KEY_INTENT:intent}
在
system_server
进程中进行反序列化,将恶意KEY_INTENT
的内容读入到mData
中,此时,恶意KEY_INTENT
不是一个单独的键值对,因此可以逃避系统的checkIntent
检查在
system_server
进程中再次将这个 Bundle 序列化,此时通过writeLong
方法写入到 Bundle 中,因此为占据 8 个字节最终会传递到 Settings 系统应用(高权限 system 用户),在反序列化过程中,通过
readInt
方法进行读取,发生了 4 个字节的错位,因此把后面恶意KEY_INTENT
的 4 字节 length (ByteArray 4 字节对齐)当做mData
至此,键值对反序列化完成,恶意 KEY_INTENT
作为一个新的键值对就堂而皇之的出现了,最终的结果是取得 Settings 应用的权限(高权限 system 用户)发送任意 Intent,启动任意 Activity 的能力。例如,在 intent 中指定 Settings 中的 com.android.settings.password.ChooseLockPassword
为目标 Activity, 则可以在不需要原锁屏密码的情况下重设锁屏密码。
在整个过程中,最重要的就是如何绕过系统的 checkIntent
检查,需要在 Bundle 中精确布置数据,详细的可以参考 Bundle风水——Android序列化与反序列化不匹配漏洞详解 文章中的案例。
https://xz.aliyun.com/t/2364#toc-2
这类漏洞并不是个例,历史上由于代码编写人员的粗心大意,曾经出现过许多因为「序列化与反序列化不匹配系列漏洞」 导致的提权漏洞,如下所示:
CVE-2017-0806 GateKeeperResponse
CVE-2017-0664 AccessibilityNodelnfo
CVE-2017-13288 PeriodicAdvertisingReport
CVE-2017-13289 ParcelableRttResults
CVE-2017-13286 OutputConfiguration
CVE-2017-13287 VerifyCredentialResponse
CVE-2017-13310 ViewPager’s SavedState
CVE-2017-13315 DcParamObject
CVE-2017-13312 ParcelableCasData
CVE-2017-13311 ProcessStats
CVE-2018-9431 OSUInfo
CVE-2018-9471 NanoAppFilter
CVE-2018-9474 MediaPlayerTrackInfo
CVE-2018-9522 StatsLogEventWrapper
CVE-2018-9523 Parcel. wnteMapInternal0
CVE-2021-0748 ParsingPackagelmpl
CVE-2021-0928 OutputConfiguration
CVE-2021-0685 ParsedIntentInfol
CVE-2021-0921 ParsingPackagelmpl
CVE-2021-0970 GpsNavigationMessage
CVE-2021-39676 AndroidFuture
CVE-2022-20135 GateKeeperResponse
更多......
在 2021 年的时候,AOSP 中针对 Bundle 提交了一个称为 LazyBundle(9ca6a5) 的的修复,主要修复思想,在序列化时的时候,将对应数据的大小添加到头部,然后在反序列化的时候,通过检查头部去选择性跳过,在实际用到这些值的时候再去对特定数据进行反序列化。
根据 「 深蓝洞察 」的报道,该 APP 第一步利用了多个安卓手机厂商 OEM 代码中的反序列化漏洞,进行提权,当提权成功之后,通过 App 控制了用户的整个手机系统,绕过隐私合规监管,大肆收集用户的隐私信息(包括社交媒体账户资料、位置信息、Wi-Fi 信息、基站信息甚至路由器信息等)。
另外还利用手机厂商 OEM 代码中导出的 root-path FileContentProvider
,进行 System App
和敏感系统应用文件读写。进而突破沙箱机制、绕开权限系统改写系统关键配置文件为自身保活,修改用户桌面 (Launcher) 配置隐藏自身或欺骗用户实现防卸载。
不仅如此,它还进一步通过覆盖动态代码文件的方式劫持其他应用注入后门执行代码,进行更加隐蔽的长期驻留。甚至还实现了和间谍软件一样的遥控机制,通过远端“云控开关”控制非法行为的启动与暂停,来躲避检测。已有大量终端用户投诉反馈:该 App 存在莫名安装、泄漏隐私、无法卸载等问题。
我将相关违规的 dex 转成了 Java 文件,并放到了 Android 项目中,方便有兴趣的同学查看,但是这个不方便公开,有兴趣的小伙伴,可以在后台留言,回复:pdd。
原始的 dex 文件。
地址:https://github.com/davinci1010/pinduoduo_backdoor
漏洞详细的分析报告。
地址:https://github.com/davincifans101/pinduoduo_backdoor_detailed_report
拼多多 VMP 脱壳机。
地址:https://github.com/davinci1012/pinduoduo_backdoor_unpacker
拼多多脱壳后的部分代码。
地址:https://github.com/poorjobless/pinduoduo_backdoor_code
参考文章
Android 反序列化漏洞攻防史话
Bundle风水——Android序列化与反序列化不匹配漏洞详解
全文到这里就结束了,感谢你的阅读,坚持原创不易,欢迎 在看、点赞、分享 给身边的小伙伴,我会持续分享原创干货!!!
推荐阅读:
广播 goAsync 源码分析,为什么 Google 大佬都用它
公众号:ByteCode ,分享有用、有趣的硬核原创内容,Kotlin、Jetpack、性能优化、系统源码、算法及数据结构、动画、大厂面经。
👇🏻 真诚推荐你关注我👇🏻
因微信公众号更改了推送机制
可能无法及时看到最新文章
将公众号设为 星标
或常为文章点 在看
即可及时收到最新文章
欢迎前往 博客 查看更多 Kotlin、Jetpack 、动画算法图解、系统源码分析等等文章。以及开源项目、LeetCode / 剑指 offer / 国内外大厂面试题 / 多线程 题解。
https://www.hi-dhl.com